package com.fortune.conf;

/**
 * @program: fortune
 * @description:
 * @author: wwb
 * @create: 2025-04-29 20:07
 */
import java.io.*;
import java.util.*;

public class PngCompressor {

    /**
     * PNG 图片压缩核心方法
     * @param inputPath    输入文件路径
     * @param outputPath   输出文件路径
     * @param compressionLevel  压缩级别 (0-9)
     * @param scaleRatio   缩放比例 (0.1-1.0)
     * @param removeAlpha  是否移除透明通道
     */
    public static void compressPng(String inputPath,
                                   String outputPath,
                                   int compressionLevel,
                                   double scaleRatio,
                                   boolean removeAlpha) throws Exception {
        // 参数验证
        validateParams(inputPath, compressionLevel, scaleRatio);

        List<String> command = new ArrayList<>();
        command.add("ffmpeg");

        // 输入参数
        command.add("-i");
        command.add(normalizePath(inputPath));

        // 处理透明通道
        if (removeAlpha) {
            command.add("-vf");
            command.add("format=rgb24"); // 移除alpha通道
        }

        // 添加缩放滤镜
        if (scaleRatio < 1.0) {
            String scaleFilter = String.format(
                    "scale=iw*%f:ih*%f:flags=lanczos",
                    scaleRatio, scaleRatio
            );
            if (command.contains("-vf")) {
                // 合并滤镜链
                int vfIndex = command.indexOf("-vf") + 1;
                command.set(vfIndex, command.get(vfIndex) + "," + scaleFilter);
            } else {
                command.add("-vf");
                command.add(scaleFilter);
            }
        }

        // PNG专用参数
        command.add("-compression_level");
        command.add(String.valueOf(compressionLevel));
        command.add("-pred");
        command.add("mixed"); // 最佳压缩预测器
        command.add("-y");
        command.add(normalizePath(outputPath));

        executeCommand(new ProcessBuilder(command));
    }

    // 参数验证
    private static void validateParams(String inputPath,
                                       int compressionLevel,
                                       double scaleRatio) throws IOException {
        File inputFile = new File(inputPath);
        if (!inputFile.exists()) {
            throw new IOException("输入文件不存在: " + inputPath);
        }

        if (compressionLevel < 0 || compressionLevel > 9) {
            throw new IllegalArgumentException("压缩级别需在0-9之间");
        }

        if (scaleRatio <= 0 || scaleRatio > 1) {
            throw new IllegalArgumentException("缩放比例需在0.1-1.0之间");
        }
    }

    // 路径标准化处理
    private static String normalizePath(String path) {
        return new File(path).getAbsolutePath()
                .replace("\\", "/")
                .replace(" ", "%20");
    }

    // 执行FFmpeg命令
    private static void executeCommand(ProcessBuilder pb)
            throws IOException, InterruptedException {
        pb.redirectErrorStream(true);

        try {
            Process process = pb.start();
            StringBuilder output = new StringBuilder();

            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream()))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    output.append(line).append("\n");
                }
            }

            int exitCode = process.waitFor();
            if (exitCode != 0) {
                throw new IOException("FFmpeg执行失败:\n" +
                        "命令: " + String.join(" ", pb.command()) + "\n" +
                        "输出: " + output);
            }
        } catch (IOException e) {
            if (e.getMessage().contains("Cannot run program")) {
                throw new IOException("FFmpeg未安装或路径未配置", e);
            }
            throw e;
        }
    }

    /********************** 使用示例 **********************/
    public static void main(String[] args) {
        String input = "D:\\wwb\\1\\fc_image\\uncompressed\\2025\\4\\29\\c24af52fdf9f4950abc50fa79417824e.png";
        String output = "D:\\wwb\\1\\fc_image\\compressed\\2025\\4\\29\\c24af52fdf9f4950abc50fa79417824e.png";

        try {
            // 示例：最高压缩级别 + 缩放80% + 保留透明通道
            compressPng(input, output, 9, 0.8, false);

            System.out.println("PNG压缩成功！");
            System.out.println("输出文件: " + new File(output).getAbsolutePath());
        } catch (Exception e) {
            System.err.println("压缩失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
}